﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace UtilZ.Dotnet.Ex.Model
{
    /// <summary>
    /// UI绑定集合
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    [Serializable]
    public class BindingListEx<T> : BindingList<T>
    {
        /// <summary>
        /// 自定义排序
        /// </summary>
        public Action<IList<T>, PropertyDescriptor, ListSortDirection> ApplySort;

        /// <summary>
        /// 排序完成
        /// </summary>
        public Action<IList<T>> ApplySortCompleted;

        /// <summary>
        /// 构造函数
        /// </summary>
        public BindingListEx()
            : base()
        {
            
        }

        /// <summary>
        /// 重写排序
        /// </summary>
        /// <param name="prop"></param>
        /// <param name="direction"></param>
        protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
        {
            var handler = this.ApplySort;
            if (handler != null)
            {
                handler(base.Items, prop, direction);
                this.ApplySortCompleted?.Invoke(base.Items);
                return;
            }

            if (prop.PropertyType.GetInterface("IComparable") == null)
            {
                //如果成员没有实现IComparable接口,则直接返回,不支持排序
                throw new Exception(string.Format("成员:{0}没有实现IComparable接口,该字段列不支持排序", prop.Name));
            }

            int count = this.Count;
            ComparerResultType result;
            T tmpItem;
            object leftValue;
            object rightValue;
            int compareResult;

            for (int i = 0; i < count; i++)
            {
                for (int j = i + 1; j < count; j++)
                {
                    leftValue = prop.GetValue(this.Items[i]);
                    rightValue = prop.GetValue(this.Items[j]);

                    if (leftValue == null && rightValue == null)
                    {
                        result = ComparerResultType.Equal;
                    }
                    else if (leftValue == null && rightValue != null)
                    {
                        result = ComparerResultType.Less;
                    }
                    else if (leftValue != null && rightValue == null)
                    {
                        result = ComparerResultType.Greater;
                    }
                    else
                    {
                        compareResult = ((IComparable)(leftValue)).CompareTo((IComparable)(rightValue));

                        if (compareResult > 0)
                        {
                            result = ComparerResultType.Greater;
                        }
                        else if (compareResult == 0)
                        {
                            result = ComparerResultType.Equal;
                        }
                        else if (compareResult < 0)
                        {
                            result = ComparerResultType.Less;
                        }
                        else
                        {
                            throw new Exception($"奇怪的比较结果:{compareResult},左值\"{leftValue}\",右值\"{rightValue}\"");
                        }
                    }

                    if (result == ComparerResultType.Equal)
                    {
                        continue;
                    }

                    if (direction == ListSortDirection.Ascending)
                    {
                        if (result == ComparerResultType.Greater)
                        {
                            tmpItem = this.Items[i];
                            this.Items[i] = this.Items[j];
                            this.Items[j] = tmpItem;
                        }
                    }
                    else
                    {
                        if (result == ComparerResultType.Less)
                        {
                            tmpItem = this.Items[i];
                            this.Items[i] = this.Items[j];
                            this.Items[j] = tmpItem;
                        }
                    }
                }
            }

            this.ApplySortCompleted?.Invoke(base.Items);
        }

        /// <summary>
        /// 是否支持排序
        /// </summary>
        protected override bool SupportsSortingCore
        {
            get { return true; }
        }



        /// <summary>
        /// 添加集合到到当前集合中
        /// </summary>
        /// <param name="items">要添加的集合</param>
        public void AddRange(IEnumerable<T> items)
        {
            if (items == null)
            {
                return;
            }

            foreach (var item in items)
            {
                base.Add(item);
            }
        }

        /// <summary>
        /// 从当前集合中移除集合中的所有项
        /// </summary>
        /// <param name="items">移除集合</param>
        public void RemoveArrange(IEnumerable<T> items)
        {
            if (items == null)
            {
                return;
            }

            foreach (var item in items)
            {
                base.Remove(item);
            }
        }
    }

}
